import re
import logging

import yaml
from jsonpath import jsonpath

from commons import yaml_funcs

logger = logging.getLogger("extreact_utile")
g_var = {}


def verify_resp(resp):
    """
    将Response的内容转化为统一固定格式
    状态码 转 字符串
    响应头 转 字典
    响应正文（json方法） 转 属性字典
    """
    resp.status_code = str(resp.status_code)
    resp.headers = dict(resp.headers)
    try:
        resp.json = resp.json()
    except:
        resp.json = {}

    return resp


def extract_by_re(resp, var_name, attr_name, pattern, index=0):
    """
    resp：响应信息
    var_name：保存变量名
    attr_name：属性名
    pattern：(正则)规则（也是字符串，如 "aaa(,*)bbb" ）
    index：索引
    """
    logger.info(f"提取变量名：{var_name}")

    attr = getattr(resp, attr_name)  # 从resp响应对象中获取attr_name属性，没有会报错
    logger.info(f"""组装正则语法：【 re.findall("{pattern}", "{attr}")[{index}] 】""")
    res = re.findall(pattern, attr)  # 从属性中，使用正则语法pattern提取数据
    value = res[index]  # 从列表中返回数据
    logger.info(f"变量提取结果：{var_name}：{value}")
    g_var[var_name] = value  # 保存到变量
    return True


def extract_by_jsonpath(resp, var_name, attr_name, pattern, index=0):
    """
    resp：响应信息
    var_name：保存变量名
    attr_name：属性名
    pattern：(jsonpath)规则（也是字符串，如 "$..id" ）
    index：索引
    """
    logger.info(f"提取变量名：{var_name}")

    attr = getattr(resp, attr_name)  # 从resp响应对象中获取attr_name属性，没有会报错
    logger.info(f"""组装jsonpath语法：【 jsonpath({attr}, "{pattern}")[{index}] 】""")
    res = jsonpath(attr, pattern)  # 从属性中，使用jsonpath语法pattern提取数据
    value = res[index]  # 从列表中返回数据
    logger.info(f"变量提取结果：{var_name}：{value}")
    g_var[var_name] = value  # 保存到变量
    return True


def use_vars(data):
    """
    将yaml数据中的设定好的特殊字符串(变量)转化为新字符串
    其中包含函数特征 ${func(arg1, arg2)} 的字符串，捕获并执行返回函数结果
    """
    data_str = yaml.safe_dump(data)  # yaml数据转字符串

    var_name_list = re.findall(r'\${(.*)}', data_str)
    for var_name in var_name_list:
        if var_name in g_var:
            data_str = data_str.replace("${" + f"{var_name}" + "}", str(g_var[var_name]))

    # 捕获函数，并执行返回函数结果
    res = re.findall(r"""\${(.*?)\((.*?)\)}""", data_str)
    for r in res:
        func_args = []
        func_name = r[0]
        logger.info(f"捕获到热加载函数：{func_name}:({r[1]})")
        if r[1] == "": # 无参数
            pass
        elif "," not in r[1]: # 一个参数
            func_args.append(r[1])
        elif "," in r[1]: # 多个参数
            args_list = r[1].split(",")
            for i in args_list:
                func_args.append(i.strip())

        func = getattr(yaml_funcs, func_name)
        func_result = func(*func_args)
        data_str = data_str.replace("${" + f"{func_name}(" + r[1] + ")}", str(func_result))

    new_data = yaml.safe_load(data_str)  # 转回yaml数据
    return new_data
